#!/usr/bin/python

# MUC invite bot
# Copyright (C) 2009  Denis Nelubin aka Gelin
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

# http://gelin.ru
# mailto:den@gelin.ru
# xmpp:gelin@jabber.ru?message

""" This is the bot which invites you to a jabber conference.
    Just type to the bot the conference name which you want to be invited.
"""

import sys
import os.path
import logging
import xmpp
import xmpp_bot

DEFAULT_CONFIG = './invite_bot.cfg'

class InviteBot:
    """ Handler for XMPP events.
    """

    def __init__(self):
        self._log = logging.getLogger('InviteBot')
        self._conferences = {}

    def onSubsribe(self, jid, bot):
        """ Called when presence subscription is processed
        """
        text = u"""I'm the bot.
 I can invite you to any jabber conference which I can join.
 Just type me the name of the conference and I'll try to invite you there."""
        message = xmpp.Message(jid, text, typ='chat')
        self._log.info("presenting ourselves to '%s'", message.getTo())
        bot.connection.send(message)

    def onMucJoin(self, jid, bot):
        """ Called when successfully joined to conference
        """
        invites = self._conferences.setdefault(jid, [])
        for invitee in invites:
            self._sendInvite(invitee, jid, bot)
        invites = []

    def onMucJoinFailed(self, jid, error, bot):
        """ Called when joining to conference failed
        """
        invites = self._conferences.setdefault(jid, [])
        for invitee in invites:
            self._sendJoinError(invitee, jid, error, bot)
        del self._conferences[jid]

    def onUserMessage(self, message, bot):
        """ Called when ordinal message from the user received
        """
        confJid = xmpp_bot.getStripped(xmpp.JID(message.getBody().strip()))
        invites = self._conferences.setdefault(confJid, [])
        invitee = message.getFrom()
        reply = xmpp_bot.makeReplyMessage(message)
        invites.append(invitee)
        if bot.isJoined(confJid):
            for invitee in invites:
                self._sendInvite(invitee, confJid, bot)
            invites = []
        else:
            bot.joinMuc(confJid)

    def _sendInvite(self, invitee, conference, bot):
        """ Sends invitation of the person to the conference
        """
        message = xmpp.Message(xmpp_bot.getStripped(conference))
        x = message.setTag('x', namespace='http://jabber.org/protocol/muc#user')
        invite = x.setTag('invite', {'to': invitee})
        reason = invite.setTag('reason')
        reason.setData(u'Welcome to %s' % xmpp_bot.getStripped(conference))
        self._log.info('sending invite to %s to %s' % (conference, invitee))
        bot.connection.send(message)

    def _sendJoinError(self, invitee, conference, error, bot):
        """ Sends error message to the person what the invitaion is not possible
        """
        text = u'I cannot join to %s: %s' % (xmpp_bot.getStripped(conference), error)
        message = xmpp.Message(invitee, text, typ='chat')
        bot.connection.send(message)

if __name__ == '__main__':
    #logging configuration
    logLevel = os.environ.get("LOG_LEVEL", "INFO").upper()
    logging.basicConfig(level=getattr(logging, logLevel),
                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S')
    #get options
    if len(sys.argv) > 1:
        options = xmpp_bot.Options(sys.argv[1])
    else:
        options = xmpp_bot.Options(DEFAULT_CONFIG)
    #create bot
    bot = xmpp_bot.XmppBot(options)
    #bot.register(xmpp_bot.DebugHandler())
    bot.register(InviteBot())
    #start bot
    if not bot.connect():
        sys.exit(1)
    bot.serve()
